<template>
	<div class="agent-edit">
		<div class="header">
			<div class="left">
				<span>发现</span>
				<span>></span>
				<span>创建智能体</span>
			</div>
			<div class="center">
				<span>简单三步创建属于你的专属AI智能体</span>
			</div>
		</div>
		<div class="content">
			<Steps :current="step">
				<Step :status="step1Status" title="基础设定"></Step>
				<Step :status="step2Status" title="知识导入"></Step>
				<Step :status="step3Status" title="个性配置"></Step>
			</Steps>
			<div class="form">
				<Form v-show="step === 0" ref="form1" :model="model" :rules="rules" :label-width="100">
					<FormItem prop="name" label="名称：">
						<Input type="text" :maxlength="20" v-model="model.name" placeholder="请输入你的专属AI智能体名称 最多20个字符"> </Input>
					</FormItem>
					<FormItem prop="icon" label="头像：" class="upload-item">
						<Upload ref="upload" :show-upload-list="false" :format="['jpg', 'jpeg', 'png']" :max-size="100" accept=".jpg,.jpeg,.png" :on-format-error="handleFormatError" :on-exceeded-size="handleMaxSize" :before-upload="handleBeforeUpload" action="#">
							<div class="upload-image" v-if="model.icon !== ''">
								<img :src="model.icon" />
							</div>
							<div class="upload-image" v-if="model.icon === ''">
								<ShangChuan></ShangChuan>
								<span>Upload</span>
							</div>
							<div class="upload-des">
								<a>上传头像</a>
								<span>支持jpg、jpeg、png格式，不超过100Kb,建议尺寸为1:1</span>
							</div>
						</Upload>
					</FormItem>
					<FormItem prop="role" label="模型描述：">
						<Input type="textarea" :rows="3" :maxlength="500" v-model="model.role" placeholder="示例:你是一位经验丰富的英语老师（建议500字内）"> </Input>
					</FormItem>
					<FormItem prop="opening" label="开场白：">
						<Input type="textarea" :rows="3" :maxlength="50" v-model="model.opening" placeholder="请描述该角色在第一次聊天时的开场白 (建议50字内)"> </Input>
					</FormItem>
					<FormItem>
						<div class="btn-action">
							<Button type="primary" @click.prevent="handleClick">下一步</Button>
							<Button class="default" type="default" @click.prevent="handleCancel">取消</Button>
						</div>
					</FormItem>
				</Form>
				<Form v-show="step === 1" ref="form2" :model="model" :rules="rules" :label-width="100">
					<FormItem props="" label="知识库：">
						<Upload multiple action="#" :show-upload-list="false" :format="fileFormat" accept=".docx,.pdf,.xlsx,.txt,.js,.md,.pptx,.jpeg,.png,.tiff" :on-format-error="handleFileFormatError" :before-upload="handleFileUpload">
							<Button type="default" class="upload-default">
								<div class="btn-upload">
									<ShangChuanFuJian></ShangChuanFuJian>
									<span style="line-height: 2">上传文件</span>
								</div>
							</Button>
						</Upload>
						<div class="file-list" v-show="fileList.length > 0">
							<div class="file-item" v-for="(item, index) in fileList" :key="`${item.fileName}${index}`" :class="{ failed: !item.success }">
								<FuJian width="1.33rem" height="1.33rem"></FuJian>
								<span class="title">{{ item.fileName }}</span>
								<div v-if="item.loading" class="upload-loading">
									<Loading></Loading>
								</div>
								<div v-else @click="deleteDoc(item)" class="del-file">
									<Delete width="1.73rem" height="1.73rem"></Delete>
								</div>
							</div>
						</div>
						<ul class="remark-list">
							<li>知识库文件格式支持：.docx、.pdf、.xlsx、.txt、.js、.md、.pptx、.jpeg、.png、.tiff。</li>
							<li>最多可上传20个知识库文件，每个文件大小不超过50M。</li>
							<li>上传知识文件占用本地磁盘空间参考，例如：上传文件10M，则占用磁盘空间约20M。</li>
							<li>上传文件中图片信息暂时无法识别，仅支持识别文件中的文字内容。</li>
							<li>知识库文件上传后，每次对话默认搜索知识库，具体由大模型调度。</li>
						</ul>
					</FormItem>
					<FormItem label="时间同步：" prop="time_sync">
						<i-switch v-model="model.time_sync">
							<span slot="open">开</span>
							<span slot="close">关</span>
						</i-switch>
						<span class="time-sync">开启后将与现实世界时间同步</span>
					</FormItem>
					<FormItem>
						<div class="btn-action">
							<Button type="primary" @click.prevent="handleClick">下一步</Button>
							<Button class="default" type="default" @click.prevent="handlePreClick">上一步</Button>
							<Button class="default" type="default" @click.prevent="handleCancel">取消</Button>
						</div>
					</FormItem>
				</Form>
				<Form v-show="step === 2" ref="form3" :model="model" :rules="rules" :label-width="100">
					<FormItem label="短期记忆：" prop="short_memory">
						<InputNumber v-model="model.short_memory" :min="1" :max="10" :step="1"></InputNumber>
						<span class="tips" style="margin-left: 1.33rem">即最多能记忆的对话轮次，该设置项将影响对话效果，最多不超过10轮</span>
					</FormItem>
					<FormItem label="长期记忆：" prop="long_memory">
						<Checkbox v-model="model.long_memory">全文记忆</Checkbox>
						<span style="margin-left: 1.33rem" class="tips">对话历史模糊检索</span>
					</FormItem>
					<FormItem label="回复风格：" prop="style">
						<RadioGroup v-model="model.style">
							<Radio :label="1">固定输出</Radio>
							<Radio :label="2">较多变化</Radio>
							<Radio :label="3">中等变化</Radio>
							<Radio :label="4">多样化输出</Radio>
						</RadioGroup>
						<div class="tips" style="margin-top: 1.83rem">角色针对某个提问回复的多样性，会影响重新生成的多样性</div>
					</FormItem>
					<FormItem label="回复发散：" prop="top_p">
						<div class="top-p-input">
							<!-- <Progress :percent="percent" hide-info status="active"></Progress> -->
							<Slider v-model="model.top_p" show-input :min="0" :max="1" :step="0.1"></Slider>
							<!-- <InputNumber v-model="model.top_p" :min="0" :max="1" :step="0.1"></InputNumber> -->
						</div>
						<div class="tips" style="margin-top: 1.83rem">值越高代表发散性越高，同时对人设的遵循越不稳定。</div>
					</FormItem>
					<FormItem>
						<div class="btn-action">
							<Button type="primary" @click.prevent="handleClick">发布</Button>
							<Button class="default" type="default" @click.prevent="handlePreClick">上一步</Button>
							<Button class="default" type="default" @click.prevent="handleCancel">取消</Button>
						</div>
					</FormItem>
				</Form>
			</div>
		</div>
	</div>
</template>
<script>
import ShangChuan from '@/components/svg/v1/shangchuan.vue'
import ShangChuanFuJian from '@/components/svg/v1/v-shangchuanfujian.vue'
import FuJian from '@/components/svg/v1/fujian.vue'
import Delete from '@/components/svg/v1/delete.vue'
import Loading from '@/components/loading/loading.vue'
import { defaultIcon } from './components/default-icon'
import { uuid } from '@/libs/tools'
export default {
	components: {
		ShangChuan,
		ShangChuanFuJian,
		FuJian,
		Delete,
		Loading
	},
	watch: {
		step(val) {
			this.$nextTick(() => {
				if (val >= 0) {
					this.step1Status = 'process'
				}
				if (val >= 1) {
					this.step2Status = 'process'
				}
				if (val >= 2) {
					this.step3Status = 'process'
				}
			})
		}
	},
	data() {
		return {
			step: 0,
			step1Status: 'process',
			step2Status: 'wait',
			step3Status: 'wait',
			fileName: 'v-bg.svg',
			model: {
				id: '',
				name: '',
				icon: defaultIcon,
				role: '',
				opening: '',
				time_sync: true,
				short_memory: 5,
				long_memory: true,
				style: 1,
				top_p: 0.4,
				group: '我的智能体',
				type: 2
			},
			rules: {
				name: [{ required: true, message: '请填写名称！', trigger: 'blur' }],
				// icon: [{ required: true, message: '请上传头像！', trigger: 'blur' }],
				role: [{ required: true, message: '请填写模型描述！', trigger: 'blur' }],
				opening: [{ required: true, message: '请填写开场白！', trigger: 'blur' }]
			},
			fileList: [],
			fileFormat: ['docx', 'pdf', 'xlsx', 'txt', 'js', 'md', 'pptx', 'jpeg', 'png', 'tiff']
		}
	},
	computed: {
		percent() {
			return this.model.top_p * 100
		}
	},
	methods: {
		handleFormatError(file) {
			this.$Message.error({
				content: '上传文件格式不对，支持jpg、jpeg、png格式，不超过100Kb,建议尺寸为1:1。',
				duration: 3
			})
		},
		handleFileFormatError(file) {
			this.$Message.error({
				content: '上传文件格式不对，支持.docx、.pdf、.xlsx、.txt、.js、.md、.pptx、.jpeg、.png、.tiff格式。',
				duration: 3
			})
		},
		handleMaxSize(flie) {
			this.$Message.warning({
				content: '文件： ' + file.name + ' 太大，超过100Kb.',
				duration: 3
			})
		},
		handleBeforeUpload(file) {
			if (file.size > 100 * 1024) {
				this.$Message.warning({
					content: '文件： ' + file.name + ' 太大，超过100Kb.',
					duration: 3
				})
				return false
			}
			let reader = new FileReader()
			reader.onload = (event) => {
				let base64String = event.target.result
				this.model.icon = base64String
				this.fileName = file.name
			}
			reader.readAsDataURL(file)
			return false
		},
		fileToBytes(file) {
			return new Promise(function (resolve, reject) {
				let reader = new FileReader()

				reader.onload = function (e) {
					let arrayBuffer = e.target.result
					// let bytes = new Uint8Array(arrayBuffer)
					resolve(arrayBuffer)
				}

				reader.onerror = function () {
					reject(new Error('Failed to read file'))
				}

				reader.readAsDataURL(file)
			})
		},
		async handleFileUpload(file) {
			if (file.size > 50 * 1024 * 1024) {
				this.$Message.warning({
					content: '上传文件大小不超过50M',
					duration: 3
				})
				return false
			}
			if (this.fileList.length > 20) {
				this.$Message.warning({
					content: '最多支持上传20个文件',
					duration: 3
				})
				return false
			}
			// 检查文件格式
			if (!this.fileFormat.includes(file.name.split('.').pop())) {
				return false
			}
			setTimeout(async () => {
				const uid = uuid()
				this.fileList.push({ id: '', fileName: file.name, webId: uid, success: true, loading: true })
				const bytes = await this.fileToBytes(file)
				const res = await chrome.webview.hostObjects.form.SaveDocAsync(this.model.id, file.name, bytes)
				const { code, data } = JSON.parse(res)
				console.log(res)
				let item = this.fileList.find((el) => {
					return el.webId === uid
				})
				if (code === '0') {
					item.loading = false
					item.id = data
				} else {
					item.success = false
					item.loading = false
					this.$Message.error({ content: '上传失败！' })
				}
			}, 0)
			return false
		},
		async deleteDoc(item) {
			if (item.id === '') {
				const index = this.fileList.findIndex((el) => {
					return el.webId === item.webId
				})
				this.flieList.splice(index, 1)
			} else {
				// console.log(item)
				// console.log(this.fileList)
				const index = this.fileList.findIndex((el) => {
					return el.id === item.id
				})
				// console.log(index)
				const res = await chrome.webview.hostObjects.form.DeleteDocAsync(item.id)
				const { code } = JSON.parse(res)
				if (code === '0') {
					this.fileList.splice(index, 1)
				} else {
					this.$Message.error({ content: '删除失败！' })
				}
			}
		},
		handleCancel() {
			this.$router.push({
				name: 'discover_list'
			})
		},
		handleClick() {
			this.$refs[`form${this.step + 1}`].validate(async (valid) => {
				if (valid) {
					const info = { ...this.model }
					info.icon_name = this.fileName
					console.log(info)
					const res = await chrome.webview.hostObjects.form.SaveAsync(JSON.stringify(info))
					console.log(res)
					const { code, message, data } = JSON.parse(res)
					if (code === '0') {
						this.$Message.success({ content: '保存成功' })
						this.model.id = data
						if (this.step === 2) {
							this.$router.push({
								name: 'discover_list'
							})
						} else {
							this.step = this.step + 1
						}
					} else {
						this.$Message.error({ content: message })
					}
				}
			})
		},
		handlePreClick() {
			this.step--
		},
		async getDocList() {
			const res = await chrome.webview.hostObjects.form.GetDocListAsync(this.model.id)
			const { code, data } = JSON.parse(res)
			if (code === '0') {
				this.fileList = data.map((el) => {
					return {
						id: el.id,
						fileName: el.name,
						webId: '',
						success: true,
						loading: false
					}
				})
			}
		},
		getFileExtensionFromBase64(base64String) {
			const mimeRegex = /^data:(.+);base64,/
			const mimeType = base64String.match(mimeRegex)[1]

			if (mimeType === 'image/svg+xml') {
				return 'svg'
			}

			return mimeType.split('/')[1]
		},
		async getAgent() {
			const res = await chrome.webview.hostObjects.form.GetAsync(this.model.id)
			const { code, data } = JSON.parse(res)
			if (code === '0') {
				console.log(data)
				// data.icon = `data:image/png;base64,${data.icon}`
				this.model = data
				this.fileName = `icon.${this.getFileExtensionFromBase64(data.icon)}`
			}
		}
	},
	mounted() {
		if (this.$route.query.id) {
			this.model.id = this.$route.query.id
			this.getAgent()
			this.getDocList()
		}
	}
}
</script>
<style lang="less" scoped>
.agent-edit {
	padding: 2.5rem 2.83rem;
	.header {
		display: flex;
		.left {
			font-family: PingFangSC-Semibold;
			font-size: 1.17rem;
			color: var(--setting-text-title-color);
			letter-spacing: 0;
			font-weight: 600;
			span {
				margin-right: 0.3rem;
			}
			span:last-child {
				margin-right: 2rem;
			}
		}
		.center {
			font-family: PingFangSC-Regular;
			font-size: 1.17rem;
			color: #999999;
			letter-spacing: 0;
			font-weight: 400;
		}
	}
	.content {
		padding: 3.5rem 6rem;
		display: flex;
		justify-content: center;
		flex-direction: column;
		/deep/.ivu-steps-item {
			display: flex;
			align-items: center;
		}
		/deep/.ivu-steps-item:not(:first-child) {
			margin-left: 2rem;
		}
		/deep/.ivu-steps .ivu-steps-title {
			padding-right: 2rem;
		}
		/deep/.ivu-steps .ivu-steps-head-inner {
			width: 32px;
			height: 32px;
			line-height: 32px;
		}
		/deep/.ivu-steps .ivu-steps-head-inner > .ivu-steps-icon {
			line-height: 32px;
			font-size: 32px;
		}
		.form {
			padding: 2.67rem 3rem;
			/deep/.ivu-form .ivu-form-item-label {
				font-size: 1.17rem !important;
			}
			/deep/.ivu-input {
				font-size: 1.17rem !important;
			}
			/deep/.ivu-upload-select {
				display: flex;
			}
			.btn-action {
				button {
					margin-right: 1.04rem;
					margin-top: 0.5rem;
				}
			}
			.upload-image {
				--width: 6.67rem;
				width: var(--width);
				height: var(--width);
				background: #f8f8f8;
				border: 0.08rem dashed rgba(210, 210, 210, 1);
				border-radius: calc(var(--width) / 2);
				display: flex;
				flex-direction: column;
				justify-content: center;
				align-items: center;
				cursor: pointer;
				img {
					width: 6.67rem;
					height: 6.67rem;
					border-radius: calc(var(--width) / 2);
				}
			}
			.upload-des {
				display: flex;
				flex-direction: column;
				align-items: flex-start;
				justify-content: center;
				margin-left: 1.67rem;
				a {
					font-family: PingFangSC-Regular;
					font-size: 1.17rem;
					color: #1890ff;
					text-align: right;
					font-weight: 400;
				}
				span {
					font-family: PingFangSC-Regular;
					font-size: 1.17rem;
					color: rgba(0, 0, 0, 0.85);
					text-align: right;
					font-weight: 400;
				}
			}
			.upload-item {
				display: flex;
				align-items: center;
				/deep/.ivu-form-item-content {
					margin-left: 0 !important;
				}
			}
		}
		.btn-upload {
			display: flex;
			span {
				margin-right: 0.4rem;
			}
		}
		.remark-list {
			li {
				font-family: PingFangSC-Regular;
				font-size: 1.17rem;
				color: var(--tips-color);
				line-height: 1.83rem;
				font-weight: 400;
				margin-top: 1.5rem;
			}
		}
		.time-sync {
			font-family: PingFangSC-Regular;
			font-size: 1.17rem;
			color: rgba(102, 102, 102, 0.85);
			text-align: right;
			line-height: 1.83rem;
			font-weight: 400;
			margin-left: 0.7rem;
		}
		.file-list {
			display: flex;
			// flex-wrap: wrap;
			flex-direction: column;
			margin-top: 1.5rem;
			max-height: 14rem;
			overflow-y: auto;

			.file-item {
				display: flex;
				align-items: center;
				margin-bottom: 1rem;
				// padding: 0.5rem 1rem;
				// background: #f8f8f8;
				// border-radius: 1.33rem;
				justify-content: space-between;
				&:hover {
					background: #f8f8f8;
					border-radius: 4px;
				}
				.title {
					font-family: PingFangSC-Regular;
					font-size: 1.17rem;
					color: #1890ff;
					text-align: left;
					font-weight: 400;
					margin-left: 0.75rem;
					flex: 1;
				}
				.upload-loading/deep/.loading {
					width: 16px;
					height: 16px;
				}
				.upload-loading/deep/.loading > div {
					width: 4px;
					height: 4px;
				}
				.del-file {
					cursor: pointer;
				}
			}
			/deep/.fill-color {
				fill: #d8d8d8;
			}
			/deep/.gfill-color {
				fill: #d8d8d8;
			}
			.failed {
				.title {
					color: #ff0003;
				}
				/deep/.fill-color {
					fill: #ff0003;
				}
				/deep/.gfill-color {
					fill: #ff0003;
				}
			}
		}
		.tips {
			font-family: PingFangSC-Regular;
			font-size: 1.17rem;
			color: var(--tips-color);
			line-height: 1.83rem;
			font-weight: 400;
		}
	}
}
html[data-theme='dark'] .btn-action .default,
html[data-theme='dark'] .upload-default {
	background: rgba(255, 255, 255, 0.34);
	color: rgba(255, 255, 255, 0.87);
	border: rgba(255, 255, 255, 0.34);
	.btn-upload {
		/deep/.fill-color {
			fill: rgba(255, 255, 255, 0.87);
		}
	}
}
html[data-theme='dark'] .del-file {
	/deep/.fill-color {
		fill: #7d7d7d;
	}
}
html[data-theme='dark'] .agent-edit {
	/deep/.ivu-input-number-input {
		color: rgba(255, 255, 255, 0.87);
	}
	/deep/.ivu-checkbox-inner {
		border-color: var(--ivu-link-hover-color);
		background-color: var(--ivu-primary-color);
	}
	/deep/.ivu-checkbox-checked .ivu-checkbox-inner {
		border-color: #f38800;
		background-color: #f38800;
	}
	/deep/.ivu-checkbox-wrapper {
		color: rgba(255, 255, 255, 0.87);
	}
	/deep/.ivu-radio-wrapper {
		color: rgba(255, 255, 255, 0.87);
	}
	/deep/.ivu-radio-inner {
		background-color: rgba(255, 255, 255, 0.2);
	}
	/deep/.ivu-radio-wrapper-checked.ivu-radio-border {
		border: 1px solid rgba(254, 142, 0, 1);
	}
	/deep/.ivu-radio-checked .ivu-radio-inner {
		background-color: #fff;
	}
	.file-list {
		.file-item:hover {
			background: rgba(255, 255, 255, 0.15);
		}
	}
}
</style>
